from typing import Any
from app.shared.constants.status_codes import BusinessCode, BUSINESS_CODE_MESSAGES


class BaseException(Exception):
    """基础异常类"""
    
    def __init__(self, message: str = None, code: int = None, details: Any = None):
        self.message = message or "系统错误"
        self.code = code or BusinessCode.OPERATION_FAILED
        self.details = details
        super().__init__(self.message)


class ValidationException(BaseException):
    """验证异常"""
    
    def __init__(self, message: str = None, field: str = None, value: Any = None):
        super().__init__(
            message or "数据验证失败",
            BusinessCode.PARAM_ERROR,
            {"field": field, "value": value}
        )
        self.field = field
        self.value = value


class AuthenticationException(BaseException):
    """认证异常"""
    
    def __init__(self, message: str = None):
        super().__init__(
            message or "认证失败",
            BusinessCode.USER_NOT_LOGIN
        )


class AuthorizationException(BaseException):
    """授权异常"""
    
    def __init__(self, message: str = None):
        super().__init__(
            message or "权限不足",
            BusinessCode.PERMISSION_DENIED
        )


class NotFoundException(BaseException):
    """资源不存在异常"""
    
    def __init__(self, resource: str = "资源", resource_id: Any = None):
        message = f"{resource}不存在"
        if resource_id:
            message += f"，ID：{resource_id}"
        
        super().__init__(
            message,
            BusinessCode.DATA_NOT_FOUND,
            {"resource": resource, "resource_id": resource_id}
        )


class ConflictException(BaseException):
    """资源冲突异常"""
    
    def __init__(self, resource: str = "资源", message: str = None):
        super().__init__(
            message or f"{resource}已存在",
            BusinessCode.DATA_ALREADY_EXISTS,
            {"resource": resource}
        )


class BusinessException(BaseException):
    """业务异常"""
    
    def __init__(self, code: int, message: str = None, details: Any = None):
        super().__init__(
            message or BUSINESS_CODE_MESSAGES.get(code, "业务异常"),
            code,
            details
        )